{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "Image Classification on Fashion MNIST with TensorFlow-Quantum and Cirq.ipynb",
      "provenance": [],
      "collapsed_sections": [],
      "toc_visible": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ul073WDztsNU"
      },
      "source": [
        "# Image Classification on Fashion MNIST with TensorFlow-Quantum and Cirq"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "FDtXZb18m0Jq"
      },
      "source": [
        "## About the Dataset and QML"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ecq9vXs7opLM"
      },
      "source": [
        "The original MNIST dataset contains a lot of handwritten digits. People from AI/ML/Data Science community love this dataset and use it as a benchmark to validate their algorithms. In fact, MNIST is often the first dataset they would try on. ***“If it doesn’t work on MNIST, it won’t work at all”***, they said. ***“Well, if it does work on MNIST, it may still fail on others.”*** Fashion-MNIST is intended to serve as a direct drop-in replacement for the original MNIST dataset to benchmark machine learning algorithms, as it shares the same image size and the structure of training and testing splits."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "TBbNH7k6qSgt"
      },
      "source": [
        "We shall perform QML on Fashion MNIST dataset using TensorFLow Quantum and Cirq. \r\n",
        "\r\n",
        "[TensorFlow-Quantum](https://www.tensorflow.org/quantum/tutorials) is a great place to start learning QML and get into this amazing field. TensorFlow Quantum (TFQ) is a quantum machine learning library for rapid prototyping of hybrid quantum-classical ML models.TensorFlow Quantum focuses on quantum data and building hybrid quantum-classical models. It integrates quantum computing algorithms and logic designed in Cirq, and provides quantum computing primitives compatible with existing TensorFlow APIs, along with high-performance quantum circuit simulators. \r\n",
        "\r\n",
        "[Cirq](https://quantumai.google/cirq) is a Python software library for writing, manipulating, and optimizing quantum circuits, and then running them on quantum computers and quantum simulators. Cirq provides useful abstractions for dealing with today’s noisy intermediate-scale quantum computers, where details of the hardware are vital to achieving state-of-the-art results."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "AOCdlEjxKoRN"
      },
      "source": [
        "Today's(NISQ Era) Quantum Computer are not very powerful and have various limitations. Also, the field of Quantum Machine Learning is currently evolving. To keep things simple, we will modify the Fashion MNIST dataset by making classification on only two classes - Sandal and Ankle boot. The reason to choose these classes is that they are similar to each other and therefore, it ascertains that the classification problem doesn't become very easy. The image shape in the provided dataset is (28,28), but we need to downscale the images to classify them using QML due to the hardware restrictions. We will downscale the images so that they have the shape (4,4)."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "1mB2jAsznFZK"
      },
      "source": [
        "Number of Images in the Train Dataset - 10200\r\n",
        "\r\n",
        "Number of Images in the Validation Dataset - 1800\r\n",
        "\r\n",
        "Number of Images in the Test Dataset - 2000\r\n",
        "\r\n",
        "Size of each Image - (2,2)\r\n",
        "\r\n",
        "Type of Image - Grayscale Image\r\n",
        "\r\n",
        "Number of Labels - 2\r\n",
        "\r\n",
        "\r\n",
        "~~~\r\n",
        "Label\tDescription\r\n",
        "5\t    Sandal\r\n",
        "9\t    Ankle boot\r\n",
        "~~~"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_Xi8mJUptn42"
      },
      "source": [
        "## Installing required packages"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Xj9X94SHs7_o"
      },
      "source": [
        "# installing TensorFLow Version 2.3.1\r\n",
        "from IPython.display import clear_output\r\n",
        "!pip install -q tensorflow==2.3.1\r\n",
        "clear_output()"
      ],
      "execution_count": 1,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "jEFDCf90oOwN"
      },
      "source": [
        "# install tensorflow quantum\r\n",
        "!pip install -q tensorflow_quantum\r\n",
        "clear_output()"
      ],
      "execution_count": 2,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Kr4kAs3ipWYN"
      },
      "source": [
        "#install cirq\r\n",
        "!pip install cirq\r\n",
        "clear_output()"
      ],
      "execution_count": 3,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "4E3JNaVwu-SX"
      },
      "source": [
        "## Importing the dataset and required packages"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "otBjLV4ovAqm"
      },
      "source": [
        "import tensorflow as tf\r\n",
        "\r\n",
        "# Data Processing tools\r\n",
        "import numpy as np\r\n",
        "from sklearn.model_selection import train_test_split \r\n",
        "\r\n",
        "# QML tools\r\n",
        "import tensorflow_quantum as tfq\r\n",
        "import cirq\r\n",
        "import sympy\r\n",
        "\r\n",
        "# Visualization Tools\r\n",
        "from cirq.contrib.svg import SVGCircuit\r\n",
        "import matplotlib.pyplot as plt"
      ],
      "execution_count": 1,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "MxejhA8Iumpu",
        "outputId": "d5e04292-fb96-40c9-cb98-1a1f1724601d"
      },
      "source": [
        "#Lets print the version of cirq and tfq that we will use\r\n",
        "print(\"We are using the TensorFlow-Quantum version {}\".format(tfq.__version__))\r\n",
        "print(\"We are using the Cirq version {}\".format(cirq.__version__))"
      ],
      "execution_count": 2,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "We are using the TensorFlow-Quantum version 0.4.0\n",
            "We are using the Cirq version 0.9.1\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "nvAb6_0xnBRX"
      },
      "source": [
        "#importing the Fashion MNIST dataset from keras\r\n",
        "from tensorflow.keras.datasets import fashion_mnist as dataset"
      ],
      "execution_count": 3,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "7_xF9rR-rNFz"
      },
      "source": [
        "(X_train, y_train), (X_test, y_test) = dataset.load_data()"
      ],
      "execution_count": 4,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "kFlj0AvvrqIW",
        "outputId": "8121f0be-6284-4608-e0b6-29703f49cf9f"
      },
      "source": [
        "print(\"The shape of the X_train is {}\".format( X_train.shape))\r\n",
        "print(\"The shape of the y_train is {}\".format(y_train.shape))\r\n",
        "print(\"The shape of the X_test is {}\".format(X_test.shape))\r\n",
        "print(\"The shape of the y_test is {}\".format(y_test.shape))"
      ],
      "execution_count": 5,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "The shape of the X_train is (60000, 28, 28)\n",
            "The shape of the y_train is (60000,)\n",
            "The shape of the X_test is (10000, 28, 28)\n",
            "The shape of the y_test is (10000,)\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "jDyH0wwXwCOK"
      },
      "source": [
        "## Preprocessing the Dataset"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "3z2lgVw1wELa"
      },
      "source": [
        "def filter_data(x, y):\r\n",
        "  \"\"\"\r\n",
        "  Helper Function to filter the dataset\r\n",
        "  \"\"\"\r\n",
        "  #filter the data using labels\r\n",
        "  keep = (y == 5) | (y == 9)\r\n",
        "  x, y = x[keep], y[keep]\r\n",
        "\r\n",
        "  # convert labels to boolean\r\n",
        "  # y = True if y==5\r\n",
        "  # y = False if y==9\r\n",
        "  y = y == 5\r\n",
        "  return x,y"
      ],
      "execution_count": 6,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "jQHzPIhA6og7"
      },
      "source": [
        "#Filter the train set\r\n",
        "X_train, y_train = filter_data(X_train, y_train)\r\n",
        "\r\n",
        "#Filter the test_set\r\n",
        "X_test, y_test = filter_data(X_test, y_test)"
      ],
      "execution_count": 7,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "DU7rvKtu-CSu",
        "outputId": "b258ec37-a770-4bd2-e8bb-7d1be423d2b0"
      },
      "source": [
        "# Let's have a look at the shapes of train and test data\r\n",
        "print(\"The shape of the X_train is {}\".format( X_train.shape))\r\n",
        "print(\"The shape of the y_train is {}\".format(y_train.shape))\r\n",
        "print(\"The shape of the X_test is {}\".format(X_test.shape))\r\n",
        "print(\"The shape of the y_test is {}\".format(y_test.shape))"
      ],
      "execution_count": 8,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "The shape of the X_train is (12000, 28, 28)\n",
            "The shape of the y_train is (12000,)\n",
            "The shape of the X_test is (2000, 28, 28)\n",
            "The shape of the y_test is (2000,)\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 298
        },
        "id": "Ymg4FvbDsmbO",
        "outputId": "1cef323b-481a-4e2e-ad05-54a4958be3a3"
      },
      "source": [
        "#Let's have a look at the first image from our X_train and the \r\n",
        "# corresponding label from y_train\r\n",
        "print(\"The First Image has the label {}\".format(y_train[0]))\r\n",
        "plt.imshow(X_train[0])\r\n",
        "plt.colorbar()\r\n",
        "plt.title('Visualization of the Dataset')\r\n",
        "plt.show()"
      ],
      "execution_count": 9,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "The First Image has the label False\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 432x288 with 2 Axes>"
            ]
          },
          "metadata": {
            "tags": [],
            "needs_background": "light"
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "e7QO_qj5uTN9"
      },
      "source": [
        "From the colorbar in the above visualization, it is clear that we have grayscale images in the dataset and hence their values range from 0 to 255. However, we would like to scale these pixel values in our dataset so that the values range from 0 to 1. This will help us to converge our CNN training faster"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "e3qqMcOFvr5b"
      },
      "source": [
        "#Normalizing the train and test image data\r\n",
        "X_train = X_train/255.0\r\n",
        "X_test = X_test/ 255.0"
      ],
      "execution_count": 10,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 281
        },
        "id": "Bevkendhuzsq",
        "outputId": "d1cf7cbf-a8e7-4e29-eaf9-88cfa83caa74"
      },
      "source": [
        "#Let's again have a look at the first image from our X_train and\r\n",
        "#see if we have successfully normalized the datasets\r\n",
        "plt.imshow(X_train[0])\r\n",
        "plt.colorbar()\r\n",
        "plt.title('Visualization of the Dataset')\r\n",
        "plt.show()"
      ],
      "execution_count": 11,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 432x288 with 2 Axes>"
            ]
          },
          "metadata": {
            "tags": [],
            "needs_background": "light"
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Cfgtl9kUD9H5"
      },
      "source": [
        "#Before proceeding, we need to reshape our images in the dataset\r\n",
        "X_train = X_train.reshape(X_train.shape[0], *(28,28,1))\r\n",
        "X_test = X_test.reshape(X_test.shape[0], *(28,28,1))"
      ],
      "execution_count": 12,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "cvBKLXbc_cZg"
      },
      "source": [
        "# Downscaling the images\r\n",
        "X_train = tf.image.resize(X_train, (2,2)).numpy()\r\n",
        "X_test = tf.image.resize(X_test, (2,2)).numpy()\r\n"
      ],
      "execution_count": 13,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 281
        },
        "id": "iKWbEihSJBX_",
        "outputId": "d1f35533-1c91-4ac8-8a5f-c7ba607b67c6"
      },
      "source": [
        "#Let's again have a look at the first image from our resized X_train\r\n",
        "plt.imshow(X_train[0,:,:,0])\r\n",
        "plt.colorbar()\r\n",
        "plt.title('Visualization of the Resized Dataset')\r\n",
        "plt.show()"
      ],
      "execution_count": 14,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 432x288 with 2 Axes>"
            ]
          },
          "metadata": {
            "tags": [],
            "needs_background": "light"
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "-yiNywWqP610"
      },
      "source": [
        "#Splitting the training fdataset into train and validation datasets\r\n",
        "X_train, X_valid, y_train, y_valid = train_test_split(X_train, y_train, test_size = 0.15, random_state=0)"
      ],
      "execution_count": 15,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "jy57uzOT-LvY",
        "outputId": "8e655d0a-b97a-4c14-da72-185d4c16c796"
      },
      "source": [
        "print(\"The shape of the X_train is {}\".format(X_train.shape))\r\n",
        "print(\"The shape of the y_train is {}\".format(y_train.shape))\r\n",
        "print(\"The shape of the X_valid is {}\".format(X_valid.shape))\r\n",
        "print(\"The shape of the y_valid is {}\".format(y_valid.shape))"
      ],
      "execution_count": 16,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "The shape of the X_train is (10200, 2, 2, 1)\n",
            "The shape of the y_train is (10200,)\n",
            "The shape of the X_valid is (1800, 2, 2, 1)\n",
            "The shape of the y_valid is (1800,)\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "hDTiCqXpPQ4x"
      },
      "source": [
        "## Data Encoding"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "j54vI9ydZUfc"
      },
      "source": [
        "Steps involved in Data Encoding:\r\n",
        "\r\n",
        "* Processing pixel values for binary encoding\r\n",
        "\r\n",
        "* Converting Cirq Circuits to tfq tensors"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "dJCkl4_tfERJ"
      },
      "source": [
        "**Step 1: Processing Pixel Values for Binary Encoding**"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "mhxgJsxhfuzZ"
      },
      "source": [
        "# FLattening the images\r\n",
        "X_train = X_train.reshape(X_train.shape[0], *(1,4,1))\r\n",
        "X_valid = X_valid.reshape(X_valid.shape[0], *(1,4,1))\r\n",
        "X_test = X_test.reshape(X_test.shape[0], *(1,4,1))"
      ],
      "execution_count": 17,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "DtYwPoLPd6iH"
      },
      "source": [
        "### Processing X_train"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "FuJABwN8eGNc",
        "outputId": "ba9c48cd-51f2-4cc7-8851-3bebebcfff35"
      },
      "source": [
        "#Let's have a look on the first example\r\n",
        "print(X_train[0])"
      ],
      "execution_count": 18,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "[[[0.        ]\n",
            "  [0.41568628]\n",
            "  [0.7137255 ]\n",
            "  [0.73921573]]]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "rIzIktKfhXRi"
      },
      "source": [
        "\r\n",
        "def binary_encode(X,threshold=0.5):\r\n",
        "  \"\"\"\r\n",
        "  Encodes the given datset to use binary encoding\r\n",
        "\r\n",
        "  Parameters:\r\n",
        "  X(array) : Image data to be processed for encoding\r\n",
        "  threshold(float): Threshold for binary encoding, 0.5 by default\r\n",
        "\r\n",
        "  Returns:\r\n",
        "  encoded_images(array): Binary encoded Image Data\r\n",
        "\r\n",
        "  \"\"\" \r\n",
        "  encoded_images = list()\r\n",
        "  for image in X:\r\n",
        "    # pixel value is 1 if it's greater than threshold or else zero\r\n",
        "    encoded_image = [1 if j>threshold else 0 for j in image[0]]\r\n",
        "    encoded_images.append(encoded_image)\r\n",
        "  return np.array(encoded_images)"
      ],
      "execution_count": 19,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "eymmTOimcxSN"
      },
      "source": [
        "X_train = binary_encode(X_train)"
      ],
      "execution_count": 20,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "sESCMm_xc47k",
        "outputId": "47746dc2-a491-4551-c314-97b1f7f2c056"
      },
      "source": [
        "# Now, Let's have a look on the first example again\r\n",
        "print(X_train[0])"
      ],
      "execution_count": 21,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "[0 0 1 1]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "PCv2dDsmfMOM",
        "outputId": "fac9a3ec-4b0a-4cd2-923f-c17b937ff14d"
      },
      "source": [
        "print(\"The shape of the X_train is {}\".format(X_train.shape))"
      ],
      "execution_count": 22,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "The shape of the X_train is (10200, 4)\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "0P6g8CypTktk"
      },
      "source": [
        "def create_circuit_from_image(encoded_image):\r\n",
        "  \"\"\"\r\n",
        "  Returns a circuit for given encoded image\r\n",
        "\r\n",
        "  Parameters:\r\n",
        "  encoded_image (array): Encoded Image\r\n",
        "\r\n",
        "  Returns:\r\n",
        "  circuit (cirq.Circuit object): cirq circuit\r\n",
        "  \"\"\"\r\n",
        "  qubits = cirq.GridQubit.rect(2,2)\r\n",
        "  circuit = cirq.Circuit()\r\n",
        "  for i, pixel in enumerate(encoded_image):\r\n",
        "    if pixel:\r\n",
        "      circuit.append(cirq.X(qubits[i]))\r\n",
        "  return circuit"
      ],
      "execution_count": 23,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "sTNIeH-2WA8-"
      },
      "source": [
        "X_train = [create_circuit_from_image(encoded_image) for encoded_image in X_train]"
      ],
      "execution_count": 24,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "g8kkNTVvWiBm",
        "outputId": "f0da20e0-7714-441c-ac66-76af44202cdc"
      },
      "source": [
        "# Let's have a look at the circuit for the first image\r\n",
        "print(X_train[0])"
      ],
      "execution_count": 25,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "(1, 0): ───X───\n",
            "\n",
            "(1, 1): ───X───\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "fUaCe4BLXM3m"
      },
      "source": [
        "Recall that the values for the first image were 0,0,1,1. This implies that we should apply X or NOT gate the last two qubuts since all the qubits are intially in the 0 states. Applying a X gate will change this state from zero to one. Therefore, we shall apply X Gate on the last two qubits. We have initialized the four qubits in a rectangular grid. Therefore, the initialized qubits are (0,0), (0,1), (1,0) and (1,1). In the above circuit diagram, note that we have a X gate on the qubits (1,0) and (1,1) which are the last two qubits. Hence, we have successfully created circuit for our image. "
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "RCU6S7WhZ3Ct"
      },
      "source": [
        "**Step 2: Converting Cirq Circuits to tfq Tensors**"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "MM-yJnfcZ2VO"
      },
      "source": [
        "X_train_tfq = tfq.convert_to_tensor(X_train)"
      ],
      "execution_count": 26,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "nRdvapAEalmd"
      },
      "source": [
        "### Processing X_valid and X_test"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "LbofYr2faX9J"
      },
      "source": [
        "X_valid = binary_encode(X_valid)\r\n",
        "X_test = binary_encode(X_test)"
      ],
      "execution_count": 27,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "V5HoVBnXbLeP"
      },
      "source": [
        "X_valid = [create_circuit_from_image(encoded_image) for encoded_image in X_valid]\r\n",
        "X_test = [create_circuit_from_image(encoded_image) for encoded_image in X_test]"
      ],
      "execution_count": 28,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "YsQE1fdFbcV0"
      },
      "source": [
        "X_valid_tfq = tfq.convert_to_tensor(X_valid)\r\n",
        "X_test_tfq = tfq.convert_to_tensor(X_test)"
      ],
      "execution_count": 29,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "2Oo5q95fPT6n"
      },
      "source": [
        "## Quantum Neural Network"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "RM86REiy7ChU"
      },
      "source": [
        "### Build the QNN"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "m_lrpb-TcCJG"
      },
      "source": [
        "Building the Quantum Neural Network involves two steps\r\n",
        "\r\n",
        "* build a class that adds gates layer by layer\r\n",
        "\r\n",
        "* define the QNN using the class from the above step"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "DycQEj54JrLW"
      },
      "source": [
        "class QNN():\r\n",
        "    def __init__(self, data_qubits, readout):\r\n",
        "      self.data_qubits = data_qubits\r\n",
        "      self.readout = readout\r\n",
        "\r\n",
        "    def add_singleQubit_gate(self,circuit, gate, qubit_index):\r\n",
        "      \"\"\"\r\n",
        "      Adds single qubit gate to the circuit\r\n",
        "      Parameters:\r\n",
        "      circuit(cirq.Circuit object): Cirq circuit\r\n",
        "      gate(cirq gate): gate to append to the circuit\r\n",
        "      qubits(list): index of qubits to apply the gate \r\n",
        "      Returns:\r\n",
        "      None\r\n",
        "      \"\"\"\r\n",
        "      for index in qubit_index:\r\n",
        "        circuit.append(gate(self.data_qubits[index]))\r\n",
        "\r\n",
        "    def add_twoQubit_gate(self,circuit, gate, qubit_index):\r\n",
        "      \"\"\"\r\n",
        "      Adds two qubit gate to the circuit\r\n",
        "      Parameters:\r\n",
        "      circuit(cirq.Circuit object): Cirq circuit\r\n",
        "      gate(cirq gate): gate to append to the circuit\r\n",
        "      qubits(list): index of qubits to apply the gate\r\n",
        "      Returns:\r\n",
        "      None\r\n",
        "      \"\"\"\r\n",
        "      if len(qubit_index)!=2:\r\n",
        "        raise Exception(\"The length of the list of indices passed for two qubit \\\r\n",
        "        gate operations must be equal to two\")\r\n",
        "      circuit.append(gate(self.data_qubits[qubit_index[0]], self.data_qubits[qubit_index[1]]))\r\n",
        "\r\n",
        "    def add_layer(self, circuit, gate, symbol_gate):\r\n",
        "      \"\"\"\r\n",
        "      Adds New Gates/Layers to the Circuit\r\n",
        "      Parameters:\r\n",
        "      circuit(cirq.Circuit object): Cirq circuit\r\n",
        "      gate(cirq gate): gate to append to the circuit\r\n",
        "      symbol_gate(string): symbol for the gate\r\n",
        "      Returns:\r\n",
        "      None\r\n",
        "      \"\"\"\r\n",
        "      for i, qubit in enumerate(self.data_qubits):\r\n",
        "        symbol = sympy.Symbol(symbol_gate+ '-' + str(i))\r\n",
        "        circuit.append(gate(qubit, self.readout)**symbol)\r\n"
      ],
      "execution_count": 30,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "sQxpS03x1VKT"
      },
      "source": [
        "def create_qnn():\r\n",
        "    \"\"\"Create a QNN model circuit and readout operation to go along with it.\"\"\"\r\n",
        "    data_qubits = cirq.GridQubit.rect(2,2)  # a 4x4 grid.\r\n",
        "    readout = cirq.GridQubit(-1, -1)         # a single qubit at [-1,-1]\r\n",
        "    circuit = cirq.Circuit()\r\n",
        "\r\n",
        "    # Prepare the readout qubit.\r\n",
        "    circuit.append(cirq.X(readout))\r\n",
        "    circuit.append(cirq.H(readout))\r\n",
        "\r\n",
        "    qnn = QNN(\r\n",
        "        data_qubits = data_qubits,\r\n",
        "        readout=readout)\r\n",
        "    \r\n",
        "    \"\"\"\r\n",
        "    # Though we don't use single and double Qubit Gates in our Circuit, we provide \r\n",
        "    # the methods \"add_singleQubit_gate\" and \"add_twoQubit_gate\" for our Class QNN\r\n",
        "    # that can be used to add Single and Double Qubit Gates respectively.\r\n",
        "    # An exmaple is shown below:\r\n",
        "\r\n",
        "    #Add Hadamard Gates\r\n",
        "    qnn.add_singleQubit_gate(circuit, cirq.H, [0,1,2,3])\r\n",
        "\r\n",
        "    #Add CNOT gates\r\n",
        "    qnn.add_twoQubit_gate(circuit, cirq.CNOT, [0, 1])\r\n",
        "    qnn.add_twoQubit_gate(circuit, cirq.CNOT, [2, 3])\r\n",
        "    \"\"\"\r\n",
        "\r\n",
        "    # Add the ising coupling XX gate\r\n",
        "    qnn.add_layer(circuit, cirq.XX, \"xx\")\r\n",
        "    qnn.add_layer(circuit, cirq.ZZ, \"zz\")\r\n",
        "\r\n",
        "    # Finally, prepare the readout qubit.\r\n",
        "    circuit.append(cirq.H(readout))\r\n",
        "\r\n",
        "    return circuit, cirq.Z(readout)"
      ],
      "execution_count": 31,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "bkW8IUUj3Ats"
      },
      "source": [
        "qmodel, model_readout = create_qnn()"
      ],
      "execution_count": 32,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 288
        },
        "id": "B8SigYUiGE0g",
        "outputId": "6846e686-5f70-46d2-881a-06a582d66f42"
      },
      "source": [
        "#Let's have a look at our Qauntum Circuit that will perform the classification\r\n",
        "SVGCircuit(qmodel)"
      ],
      "execution_count": 33,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "findfont: Font family ['Arial'] not found. Falling back to DejaVu Sans.\n"
          ],
          "name": "stderr"
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<cirq.contrib.svg.svg.SVGCircuit at 0x7f11f5d14950>"
            ],
            "image/svg+xml": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1097.236875\" height=\"250.0\"><line x1=\"39.810625\" x2=\"1067.236875\" y1=\"25.0\" y2=\"25.0\" stroke=\"#1967d2\" stroke-width=\"1\" /><line x1=\"39.810625\" x2=\"1067.236875\" y1=\"75.0\" y2=\"75.0\" stroke=\"#1967d2\" stroke-width=\"1\" /><line x1=\"39.810625\" x2=\"1067.236875\" y1=\"125.0\" y2=\"125.0\" stroke=\"#1967d2\" stroke-width=\"1\" /><line x1=\"39.810625\" x2=\"1067.236875\" y1=\"175.0\" y2=\"175.0\" stroke=\"#1967d2\" stroke-width=\"1\" /><line x1=\"39.810625\" x2=\"1067.236875\" y1=\"225.0\" y2=\"225.0\" stroke=\"#1967d2\" stroke-width=\"1\" /><line x1=\"249.99353515625\" x2=\"249.99353515625\" y1=\"25.0\" y2=\"75.0\" stroke=\"black\" stroke-width=\"3\" /><line x1=\"350.73810546875006\" x2=\"350.73810546875006\" y1=\"25.0\" y2=\"125.0\" stroke=\"black\" stroke-width=\"3\" /><line x1=\"451.48267578125007\" x2=\"451.48267578125007\" y1=\"25.0\" y2=\"175.0\" stroke=\"black\" stroke-width=\"3\" /><line x1=\"552.2272460937501\" x2=\"552.2272460937501\" y1=\"25.0\" y2=\"225.0\" stroke=\"black\" stroke-width=\"3\" /><line x1=\"651.92919921875\" x2=\"651.92919921875\" y1=\"25.0\" y2=\"75.0\" stroke=\"black\" stroke-width=\"3\" /><line x1=\"750.58853515625\" x2=\"750.58853515625\" y1=\"25.0\" y2=\"125.0\" stroke=\"black\" stroke-width=\"3\" /><line x1=\"849.2478710937501\" x2=\"849.2478710937501\" y1=\"25.0\" y2=\"175.0\" stroke=\"black\" stroke-width=\"3\" /><line x1=\"947.9072070312501\" x2=\"947.9072070312501\" y1=\"25.0\" y2=\"225.0\" stroke=\"black\" stroke-width=\"3\" /><rect x=\"10.0\" y=\"5.0\" width=\"59.62125\" height=\"40\" stroke=\"black\" fill=\"white\" stroke-width=\"0\" /><text x=\"39.810625\" y=\"25.0\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-size=\"14px\" font-family=\"Arial\">(-1, -1): </text><rect x=\"10.0\" y=\"55.0\" width=\"59.62125\" height=\"40\" stroke=\"black\" fill=\"white\" stroke-width=\"0\" /><text x=\"39.810625\" y=\"75.0\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-size=\"14px\" font-family=\"Arial\">(0, 0): </text><rect x=\"10.0\" y=\"105.0\" width=\"59.62125\" height=\"40\" stroke=\"black\" fill=\"white\" stroke-width=\"0\" /><text x=\"39.810625\" y=\"125.0\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-size=\"14px\" font-family=\"Arial\">(0, 1): </text><rect x=\"10.0\" y=\"155.0\" width=\"59.62125\" height=\"40\" stroke=\"black\" fill=\"white\" stroke-width=\"0\" /><text x=\"39.810625\" y=\"175.0\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-size=\"14px\" font-family=\"Arial\">(1, 0): </text><rect x=\"10.0\" y=\"205.0\" width=\"59.62125\" height=\"40\" stroke=\"black\" fill=\"white\" stroke-width=\"0\" /><text x=\"39.810625\" y=\"225.0\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-size=\"14px\" font-family=\"Arial\">(1, 1): </text><rect x=\"89.62125\" y=\"5.0\" width=\"40\" height=\"40\" stroke=\"black\" fill=\"white\" stroke-width=\"1\" /><text x=\"109.62125\" y=\"25.0\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-size=\"18px\" font-family=\"Arial\">X</text><rect x=\"149.62125\" y=\"5.0\" width=\"40\" height=\"40\" stroke=\"black\" fill=\"white\" stroke-width=\"1\" /><text x=\"169.62125\" y=\"25.0\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-size=\"18px\" font-family=\"Arial\">H</text><rect x=\"209.62125\" y=\"55.0\" width=\"80.74457031250002\" height=\"40\" stroke=\"black\" fill=\"white\" stroke-width=\"1\" /><text x=\"249.99353515625\" y=\"75.0\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-size=\"14px\" font-family=\"Arial\">XX^(xx-0)</text><rect x=\"209.62125\" y=\"5.0\" width=\"80.74457031250002\" height=\"40\" stroke=\"black\" fill=\"white\" stroke-width=\"1\" /><text x=\"249.99353515625\" y=\"25.0\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-size=\"14px\" font-family=\"Arial\">XX</text><rect x=\"310.36582031250003\" y=\"105.0\" width=\"80.74457031250002\" height=\"40\" stroke=\"black\" fill=\"white\" stroke-width=\"1\" /><text x=\"350.73810546875006\" y=\"125.0\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-size=\"14px\" font-family=\"Arial\">XX^(xx-1)</text><rect x=\"310.36582031250003\" y=\"5.0\" width=\"80.74457031250002\" height=\"40\" stroke=\"black\" fill=\"white\" stroke-width=\"1\" /><text x=\"350.73810546875006\" y=\"25.0\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-size=\"14px\" font-family=\"Arial\">XX</text><rect x=\"411.11039062500004\" y=\"155.0\" width=\"80.74457031250002\" height=\"40\" stroke=\"black\" fill=\"white\" stroke-width=\"1\" /><text x=\"451.48267578125007\" y=\"175.0\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-size=\"14px\" font-family=\"Arial\">XX^(xx-2)</text><rect x=\"411.11039062500004\" y=\"5.0\" width=\"80.74457031250002\" height=\"40\" stroke=\"black\" fill=\"white\" stroke-width=\"1\" /><text x=\"451.48267578125007\" y=\"25.0\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-size=\"14px\" font-family=\"Arial\">XX</text><rect x=\"511.85496093750004\" y=\"205.0\" width=\"80.74457031250002\" height=\"40\" stroke=\"black\" fill=\"white\" stroke-width=\"1\" /><text x=\"552.2272460937501\" y=\"225.0\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-size=\"14px\" font-family=\"Arial\">XX^(xx-3)</text><rect x=\"511.85496093750004\" y=\"5.0\" width=\"80.74457031250002\" height=\"40\" stroke=\"black\" fill=\"white\" stroke-width=\"1\" /><text x=\"552.2272460937501\" y=\"25.0\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-size=\"14px\" font-family=\"Arial\">XX</text><rect x=\"612.59953125\" y=\"55.0\" width=\"78.65933593750002\" height=\"40\" stroke=\"black\" fill=\"white\" stroke-width=\"1\" /><text x=\"651.92919921875\" y=\"75.0\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-size=\"14px\" font-family=\"Arial\">ZZ^(zz-0)</text><rect x=\"612.59953125\" y=\"5.0\" width=\"78.65933593750002\" height=\"40\" stroke=\"black\" fill=\"white\" stroke-width=\"1\" /><text x=\"651.92919921875\" y=\"25.0\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-size=\"14px\" font-family=\"Arial\">ZZ</text><rect x=\"711.2588671875001\" y=\"105.0\" width=\"78.65933593750002\" height=\"40\" stroke=\"black\" fill=\"white\" stroke-width=\"1\" /><text x=\"750.58853515625\" y=\"125.0\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-size=\"14px\" font-family=\"Arial\">ZZ^(zz-1)</text><rect x=\"711.2588671875001\" y=\"5.0\" width=\"78.65933593750002\" height=\"40\" stroke=\"black\" fill=\"white\" stroke-width=\"1\" /><text x=\"750.58853515625\" y=\"25.0\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-size=\"14px\" font-family=\"Arial\">ZZ</text><rect x=\"809.9182031250001\" y=\"155.0\" width=\"78.65933593750002\" height=\"40\" stroke=\"black\" fill=\"white\" stroke-width=\"1\" /><text x=\"849.2478710937501\" y=\"175.0\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-size=\"14px\" font-family=\"Arial\">ZZ^(zz-2)</text><rect x=\"809.9182031250001\" y=\"5.0\" width=\"78.65933593750002\" height=\"40\" stroke=\"black\" fill=\"white\" stroke-width=\"1\" /><text x=\"849.2478710937501\" y=\"25.0\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-size=\"14px\" font-family=\"Arial\">ZZ</text><rect x=\"908.5775390625001\" y=\"205.0\" width=\"78.65933593750002\" height=\"40\" stroke=\"black\" fill=\"white\" stroke-width=\"1\" /><text x=\"947.9072070312501\" y=\"225.0\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-size=\"14px\" font-family=\"Arial\">ZZ^(zz-3)</text><rect x=\"908.5775390625001\" y=\"5.0\" width=\"78.65933593750002\" height=\"40\" stroke=\"black\" fill=\"white\" stroke-width=\"1\" /><text x=\"947.9072070312501\" y=\"25.0\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-size=\"14px\" font-family=\"Arial\">ZZ</text><rect x=\"1007.236875\" y=\"5.0\" width=\"40\" height=\"40\" stroke=\"black\" fill=\"white\" stroke-width=\"1\" /><text x=\"1027.236875\" y=\"25.0\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-size=\"18px\" font-family=\"Arial\">H</text></svg>"
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 33
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "fi0bmTsp3VHB"
      },
      "source": [
        "model = tf.keras.Sequential([\r\n",
        "                             \r\n",
        "    # The input is the data-circuit, encoded as a tf.string\r\n",
        "    tf.keras.layers.Input(shape=(), dtype=tf.string),\r\n",
        "\r\n",
        "    \r\n",
        "    # The PQC stands for Paramaterized Quantum Circuit\r\n",
        "    # This returns the expectation value\r\n",
        "    tfq.layers.PQC(qmodel, model_readout),\r\n",
        "])"
      ],
      "execution_count": 34,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "-Es8_ATXDFL6"
      },
      "source": [
        "# To use Hinge Loss, we convert the labels to 1 and -1\r\n",
        "y_train_h = np.array([1 if i==1 else -1 for i in y_train ])\r\n",
        "y_valid_h = np.array([1 if i==1 else -1 for i in y_valid ])\r\n",
        "y_test_h = np.array([1 if i==1 else -1 for i in y_test ])"
      ],
      "execution_count": 35,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "tueGJaAWOtWf",
        "outputId": "8389a3a7-5194-4f29-b143-b9abb13bad2a"
      },
      "source": [
        "# Let's have a look at the first label from the training dataset\r\n",
        "print(y_train_h[0])"
      ],
      "execution_count": 36,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "1\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Ifriy2HyoI-O"
      },
      "source": [
        "# Define the custom Hinge Accuracy\r\n",
        "def hinge_accuracy(y_true, y_pred):\r\n",
        "    y_true = tf.squeeze(y_true) > 0.0\r\n",
        "    y_pred = tf.squeeze(y_pred) > 0.0\r\n",
        "    result = tf.cast(y_true == y_pred, tf.float32)\r\n",
        "\r\n",
        "    return tf.reduce_mean(result)"
      ],
      "execution_count": 37,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "WUewMTq87Hl3"
      },
      "source": [
        "### Train the QNN"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "klSZErcc3kAz"
      },
      "source": [
        "model.compile(\r\n",
        "    loss=tf.keras.losses.Hinge(),\r\n",
        "    optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),\r\n",
        "    metrics=[hinge_accuracy])"
      ],
      "execution_count": 38,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "nO3eEigt4HgT",
        "outputId": "4d4dceb7-98e7-4e65-e46c-c58f04bf7199"
      },
      "source": [
        "qnn_history = model.fit(\r\n",
        "      X_train_tfq, y_train_h,\r\n",
        "      batch_size=64,\r\n",
        "      epochs=10,\r\n",
        "      verbose=1,\r\n",
        "      validation_data=(X_valid_tfq, y_valid_h))"
      ],
      "execution_count": 39,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Epoch 1/10\n",
            "160/160 [==============================] - 4s 24ms/step - loss: 0.7917 - hinge_accuracy: 0.6983 - val_loss: 0.5622 - val_hinge_accuracy: 0.7915\n",
            "Epoch 2/10\n",
            "160/160 [==============================] - 4s 25ms/step - loss: 0.5260 - hinge_accuracy: 0.7600 - val_loss: 0.4469 - val_hinge_accuracy: 0.7915\n",
            "Epoch 3/10\n",
            "160/160 [==============================] - 4s 26ms/step - loss: 0.4849 - hinge_accuracy: 0.7592 - val_loss: 0.4298 - val_hinge_accuracy: 0.7915\n",
            "Epoch 4/10\n",
            "160/160 [==============================] - 4s 24ms/step - loss: 0.4735 - hinge_accuracy: 0.7602 - val_loss: 0.4215 - val_hinge_accuracy: 0.7915\n",
            "Epoch 5/10\n",
            "160/160 [==============================] - 7s 43ms/step - loss: 0.4537 - hinge_accuracy: 0.7750 - val_loss: 0.4058 - val_hinge_accuracy: 0.8626\n",
            "Epoch 6/10\n",
            "160/160 [==============================] - 6s 39ms/step - loss: 0.4216 - hinge_accuracy: 0.8410 - val_loss: 0.3914 - val_hinge_accuracy: 0.8351\n",
            "Epoch 7/10\n",
            "160/160 [==============================] - 4s 26ms/step - loss: 0.4009 - hinge_accuracy: 0.8339 - val_loss: 0.3904 - val_hinge_accuracy: 0.8351\n",
            "Epoch 8/10\n",
            "160/160 [==============================] - 4s 25ms/step - loss: 0.3951 - hinge_accuracy: 0.8344 - val_loss: 0.3925 - val_hinge_accuracy: 0.8351\n",
            "Epoch 9/10\n",
            "160/160 [==============================] - 4s 26ms/step - loss: 0.3937 - hinge_accuracy: 0.8025 - val_loss: 0.3947 - val_hinge_accuracy: 0.7958\n",
            "Epoch 10/10\n",
            "160/160 [==============================] - 4s 24ms/step - loss: 0.3932 - hinge_accuracy: 0.8023 - val_loss: 0.3959 - val_hinge_accuracy: 0.7958\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "WBY-ECy54qyC",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "d53e8a69-88d1-48b2-87b0-318bd85e58d6"
      },
      "source": [
        "model.evaluate(X_test_tfq, y_test_h)"
      ],
      "execution_count": 40,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "63/63 [==============================] - 0s 8ms/step - loss: 0.3747 - hinge_accuracy: 0.8229\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[0.37472206354141235, 0.8229166865348816]"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 40
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "dw6i8L1RQIUI"
      },
      "source": [
        "## Visualize the Results"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 295
        },
        "id": "NK6Aw5LdOiWh",
        "outputId": "7b365ca6-0d5a-4a23-b049-4a505697b079"
      },
      "source": [
        "# Visualize Accuracy\r\n",
        "plt.plot(qnn_history.history['hinge_accuracy'])\r\n",
        "plt.plot(qnn_history.history['val_hinge_accuracy'])\r\n",
        "plt.title('Model Accuracy')\r\n",
        "plt.xlabel('Epoch')\r\n",
        "plt.ylabel('Accuracy')\r\n",
        "plt.legend(['train','test'],loc=\"best\")\r\n",
        "plt.show()"
      ],
      "execution_count": 41,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": [],
            "needs_background": "light"
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 295
        },
        "id": "9IbgVjZQRAue",
        "outputId": "aeb4d475-dfe0-440e-a10e-2744a7e2ffbe"
      },
      "source": [
        "# Visualize Loss\r\n",
        "plt.plot(qnn_history.history['loss'])\r\n",
        "plt.plot(qnn_history.history['val_loss'])\r\n",
        "plt.title('Model Loss')\r\n",
        "plt.xlabel('Epoch')\r\n",
        "plt.ylabel('Loss')\r\n",
        "plt.legend(['train','test'],loc=\"best\")\r\n",
        "plt.show()"
      ],
      "execution_count": 42,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": [],
            "needs_background": "light"
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "nxx-qCBIRcih"
      },
      "source": [
        "## Save The Model Weights"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Sh4pazWbRjR_"
      },
      "source": [
        "#Saving the weights\r\n",
        "model.save_weights('/content/sample_data/QModelWeights')"
      ],
      "execution_count": 44,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "iXLmchzKapew"
      },
      "source": [
        "## Refernces"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_fx9p7mparf3"
      },
      "source": [
        "* https://www.tensorflow.org/quantum/tutorials/mnist\r\n",
        "* https://quantumai.google/cirq/tutorials\r\n",
        "* [Paper by Farhi et al.](https://arxiv.org/pdf/1802.06002.pdf)\r\n",
        "* [Paper by Dmitri Maslov](https://www.google.com/url?sa=t&source=web&rct=j&url=https://arxiv.org/pdf/1603.07678&ved=2ahUKEwi86KbBlfvuAhUmzDgGHfteCIsQFjAJegQIHhAC&usg=AOvVaw04beRgWLMZhYBV6GpyygHF)"
      ]
    }
  ]
}